pub fn time_info(time: &str) -> String {
    let datetime = DateTime::from_str(time);

    let this_inline_data = get_inline_data(datetime.year);
    let next_inline_data = get_inline_data(datetime.year + 1);

    let day_offset = datetime.day_of_this_year();

    let arg1 = datetime.this_year_day_count() - day_offset - 1;

    let arg2 = if this_inline_data.lunar_first_day_day > datetime {
        this_inline_data.lunar_first_day_day.day_of_this_year() - datetime.day_of_this_year() - 1
    } else {
        arg1 + next_inline_data.lunar_first_day_day.day_of_this_year()
    };

    let first_thursday_offset = (4 + 7 - this_inline_data.first_week_day as u16) % 7;
    let next_thursday_offset = (4 + 7 - next_inline_data.first_week_day as u16) % 7;

    let mut arg0 = (day_offset + 3 - first_thursday_offset) / 7;

    if next_thursday_offset + arg1 < 3 {
        arg0 = 0
    };

    format!("{},{},{}", arg0 + 1, arg1, arg2)
}

#[derive(PartialEq, Eq, PartialOrd, Ord)]
pub struct DateTime {
    year: u32,
    month: u8,
    day: u8,
}

impl DateTime {
    pub fn from_str(text: &str) -> Self {
        let mut iter = text.split('-');
        let year = u32::from_str_radix(iter.next().unwrap(), 10).unwrap();
        let month = u8::from_str_radix(iter.next().unwrap(), 10).unwrap();
        let day = u8::from_str_radix(iter.next().unwrap(), 10).unwrap();
        Self { year, month, day }
    }

    pub fn this_year_day_count(&self) -> u16 {
        if is_leap_year(self.year) {
            366
        } else {
            365
        }
    }

    /// 从0开始
    pub fn day_of_this_year(&self) -> u16 {
        let is_leap_year = is_leap_year(self.year);
        let mut out = 0;
        for month in 1..=12 {
            if month < self.month {
                let month_day_count = match month {
                    1 => 31,
                    2 => 28 + is_leap_year as u16,
                    3 => 31,
                    4 => 30,
                    5 => 31,
                    6 => 30,
                    7 => 31,
                    8 => 31,
                    9 => 30,
                    10 => 31,
                    11 => 30,
                    12 => 31,
                    _ => unreachable!(),
                };
                out += month_day_count;
                continue;
            }

            if self.month == month {
                out += self.day as u16 - 1;
                continue;
            }

            break;
        }
        out
    }
}

pub fn is_leap_year(year: u32) -> bool {
    (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)
}

// 打表的结构体
pub struct InlineData {
    /// 正月初一
    lunar_first_day_day: DateTime,

    /// 这年公历第一天是星期几
    first_week_day: u8,
}

fn get_inline_data(year: u32) -> InlineData {
    match year {
        1996 => InlineData {
            lunar_first_day_day: DateTime {
                year: 1996,
                month: 2,
                day: 19,
            },
            first_week_day: 1,
        },
        1997 => InlineData {
            lunar_first_day_day: DateTime {
                year: 1997,
                month: 2,
                day: 7,
            },
            first_week_day: 3,
        },
        1998 => InlineData {
            lunar_first_day_day: DateTime {
                year: 1998,
                month: 1,
                day: 28,
            },
            first_week_day: 4,
        },
        1999 => InlineData {
            lunar_first_day_day: DateTime {
                year: 1999,
                month: 2,
                day: 16,
            },
            first_week_day: 5,
        },
        2000 => InlineData {
            lunar_first_day_day: DateTime {
                year: 2000,
                month: 2,
                day: 5,
            },
            first_week_day: 6,
        },
        2001 => InlineData {
            lunar_first_day_day: DateTime {
                year: 2001,
                month: 1,
                day: 24,
            },
            first_week_day: 1,
        },
        2002 => InlineData {
            lunar_first_day_day: DateTime {
                year: 2002,
                month: 2,
                day: 12,
            },
            first_week_day: 2,
        },
        2003 => InlineData {
            lunar_first_day_day: DateTime {
                year: 2003,
                month: 2,
                day: 1,
            },
            first_week_day: 3,
        },
        2004 => InlineData {
            lunar_first_day_day: DateTime {
                year: 2004,
                month: 1,
                day: 22,
            },
            first_week_day: 4,
        },
        2005 => InlineData {
            lunar_first_day_day: DateTime {
                year: 2005,
                month: 2,
                day: 9,
            },
            first_week_day: 6,
        },
        2006 => InlineData {
            lunar_first_day_day: DateTime {
                year: 2006,
                month: 1,
                day: 29,
            },
            first_week_day: 7,
        },
        2007 => InlineData {
            lunar_first_day_day: DateTime {
                year: 2007,
                month: 2,
                day: 18,
            },
            first_week_day: 1,
        },
        2008 => InlineData {
            lunar_first_day_day: DateTime {
                year: 2008,
                month: 2,
                day: 7,
            },
            first_week_day: 2,
        },
        2009 => InlineData {
            lunar_first_day_day: DateTime {
                year: 2009,
                month: 1,
                day: 26,
            },
            first_week_day: 4,
        },
        2010 => InlineData {
            lunar_first_day_day: DateTime {
                year: 2010,
                month: 2,
                day: 14,
            },
            first_week_day: 5,
        },
        2011 => InlineData {
            lunar_first_day_day: DateTime {
                year: 2011,
                month: 2,
                day: 3,
            },
            first_week_day: 6,
        },
        2012 => InlineData {
            lunar_first_day_day: DateTime {
                year: 2012,
                month: 1,
                day: 23,
            },
            first_week_day: 7,
        },
        2013 => InlineData {
            lunar_first_day_day: DateTime {
                year: 2013,
                month: 2,
                day: 10,
            },
            first_week_day: 2,
        },
        2014 => InlineData {
            lunar_first_day_day: DateTime {
                year: 2014,
                month: 1,
                day: 31,
            },
            first_week_day: 3,
        },
        2015 => InlineData {
            lunar_first_day_day: DateTime {
                year: 2015,
                month: 2,
                day: 19,
            },
            first_week_day: 4,
        },
        2016 => InlineData {
            lunar_first_day_day: DateTime {
                year: 2016,
                month: 2,
                day: 8,
            },
            first_week_day: 5,
        },
        2017 => InlineData {
            lunar_first_day_day: DateTime {
                year: 2017,
                month: 1,
                day: 28,
            },
            first_week_day: 7,
        },
        2018 => InlineData {
            lunar_first_day_day: DateTime {
                year: 2018,
                month: 2,
                day: 16,
            },
            first_week_day: 1,
        },
        2019 => InlineData {
            lunar_first_day_day: DateTime {
                year: 2019,
                month: 2,
                day: 5,
            },
            first_week_day: 2,
        },
        2020 => InlineData {
            lunar_first_day_day: DateTime {
                year: 2020,
                month: 1,
                day: 25,
            },
            first_week_day: 3,
        },
        2021 => InlineData {
            lunar_first_day_day: DateTime {
                year: 2021,
                month: 2,
                day: 12,
            },
            first_week_day: 5,
        },
        2022 => InlineData {
            lunar_first_day_day: DateTime {
                year: 2022,
                month: 2,
                day: 1,
            },
            first_week_day: 6,
        },
        2023 => InlineData {
            lunar_first_day_day: DateTime {
                year: 2023,
                month: 1,
                day: 22,
            },
            first_week_day: 7,
        },
        2024 => InlineData {
            lunar_first_day_day: DateTime {
                year: 2024,
                month: 2,
                day: 10,
            },
            first_week_day: 1,
        },
        2025 => InlineData {
            lunar_first_day_day: DateTime {
                year: 2025,
                month: 1,
                day: 29,
            },
            first_week_day: 3,
        },
        2026 => InlineData {
            lunar_first_day_day: DateTime {
                year: 2026,
                month: 2,
                day: 17,
            },
            first_week_day: 4,
        },
        2027 => InlineData {
            lunar_first_day_day: DateTime {
                year: 2027,
                month: 2,
                day: 6,
            },
            first_week_day: 5,
        },
        _ => unimplemented!(),
    }
}
